#pragma once

#include <iostream>
#include <sys/epoll.h>

class Epoll
{
private:
    const static int defaultSize = 128;
    const static int defaultTimeOut = 3000;

public:
    Epoll(int timeout = defaultTimeOut)
        : _timeout(timeout)
    {}

    ~Epoll()
    {
        if(_epfd >= 0) close(_epfd);
    }

    // 创建 epoll 模型
    void CreateEpoll()
    {
        _epfd = epoll_create(defaultSize);
        if(_epfd < 0) exit(5);
    }

    // 将 socket 添加到 epoll 模型中
    bool AddSockToEpoll(int sock, uint32_t events)
    {
        events |= EPOLLET; // ET 模式
        struct epoll_event ev;
        ev.data.fd = sock;
        ev.events = events;
        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, sock, &ev);
        return n == 0;
    }

    bool DelSockFromEpoll(int sock)
    {
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sock, nullptr);
        return n == 0;
    }

    int WaitEpoll(struct epoll_event* readyEvents, int maxEvents)
    {
        return epoll_wait(_epfd, readyEvents, maxEvents, _timeout);
    }

    bool CtlEpoll(int sock, uint32_t events)
    {
        events |= EPOLLET;
        struct epoll_event ev;
        ev.data.fd = sock;
        ev.events = events;
        int n = epoll_ctl(_epfd, EPOLL_CTL_MOD, sock, &ev);
        return n == 0;
    }

private:
    int _epfd;
    int _timeout;
};